<?php

namespace GeoLite2;

use Pinenut\Model2\Embedded\ReferenceContainer\One;
use Pinenut\Model2\Embedded\Reference;
use Pinenut\Model2\Finder;

/**
 * Модель с данными локации
 * 
 * @author kosh
 *        
 */
class Block extends \Model {
	const Q = 16;
	public $fromIp, $toIp;
	public $indexIp;
	public $location;
	static function fields() {
		return array_merge ( parent::fields (), [ 
				'fromIp' => self::INT,
				'toIp' => self::INT,
				'indexIp' => self::MIXED,
				'location' => [ 
						One::className (),
						Reference::className (),
						Location::className () 
				] 
		] );
	}
	function indexes() {
		return array_merge ( parent::indexes (), [ 
				'indexIp' => [ 
						'indexIp' => Finder::ORDER_ASC 
				],
		] );
	}
	
	/**
	 * Ищем и возвращаем локейшшн по адресу
	 * 
	 * @param string $ip        	
	 * @return Location
	 */
	static function location($ip) {
		$parts = explode ( '.', $ip );
		$intIp = $parts [0] * 256 * 256 * 256 + $parts [1] * 256 * 256 + $parts [2] * 256 + $parts [3];
		$block = static::find ()
				->where ( 'indexIp', [$intIp >> static::Q], Finder::OP_IN)
				->where ( 'fromIp', $intIp, Finder::OP_LTE )
				->where ( 'toIp', $intIp, Finder::OP_GTE )->one ();
		if (! $block) {
			return null;
		}
		return (string)$block->location;
	}
	
	function beforeSave() {
		parent::beforeSave();
		// набиваем индексируемое поле
		$fromIp = $this->fromIp >> static::Q;
		$toIp = $this->toIp >> static::Q;
		$this->indexIp = [];
		for ($ip = $fromIp; $ip <= $toIp; $ip ++ ) {
			$this->indexIp[] = $ip;
		}
	}
}